import { defineStore } from 'pinia';
import { ref } from 'vue';
import { RouteLocationNormalized } from 'vue-router';

export interface TagView extends Partial<RouteLocationNormalized> {
    title?: string;
}

// setup
export const useTagsViewStore = defineStore('tagsView', () => {
    // state
    const visitedViews = ref<TagView[]>([]);
    const cachedViews = ref<string[]>([]);

    // actions
    function addVisitedView(view: TagView) {
        if (visitedViews.value.some(v => v.path === view.path)) return;
        if (view.meta && view.meta.affix) {
            visitedViews.value.unshift(
                Object.assign({}, view, {
                    title: view.meta?.title || 'no-name'
                })
            );
        } else {
            visitedViews.value.push(
                Object.assign({}, view, {
                    title: view.meta?.title || 'no-name'
                })
            );
        }
    }

    function addCachedView(view: TagView) {
        const viewName = view.name as string;
        if (cachedViews.value.includes(viewName)) return;
        if (view.meta?.keepAlive) {
            cachedViews.value.push(viewName);
        }
    }

    function delVisitedView(view: TagView) {
        return new Promise(resolve => {
            for (const [i, v] of visitedViews.value.entries()) {
                if (v.path === view.path) {
                    visitedViews.value.splice(i, 1);
                    break;
                }
            }
            resolve([...visitedViews.value]);
        });
    }

    function delCachedView(view: TagView) {
        const viewName = view.name as string;
        return new Promise(resolve => {
            const index = cachedViews.value.indexOf(viewName);
            index > -1 && cachedViews.value.splice(index, 1);
            resolve([...cachedViews.value]);
        });
    }

    function delOtherVisitedViews(view: TagView) {
        return new Promise(resolve => {
            visitedViews.value = visitedViews.value.filter(v => {
                return v.meta?.affix || v.path === view.path;
            });
            resolve([...visitedViews.value]);
        });
    }

    function delOtherCachedViews(view: TagView) {
        const viewName = view.name as string;
        return new Promise(resolve => {
            const index = cachedViews.value.indexOf(viewName);
            if (index > -1) {
                cachedViews.value = cachedViews.value.slice(index, index + 1);
            } else {
                // if index = -1, there is no cached tags
                cachedViews.value = [];
            }
            resolve([...cachedViews.value]);
        });
    }

    function updateVisitedView(view: TagView) {
        for (let v of visitedViews.value) {
            if (v.path === view.path) {
                v = Object.assign(v, view);
                break;
            }
        }
    }

    function addView(view: TagView) {
        addVisitedView(view);
        addCachedView(view);
    }

    function delView(view: TagView) {
        return new Promise(resolve => {
            delVisitedView(view);
            delCachedView(view);
            resolve({
                visitedViews: [...visitedViews.value],
                cachedViews: [...cachedViews.value]
            });
        });
    }

    function delOtherViews(view: TagView) {
        return new Promise(resolve => {
            delOtherVisitedViews(view);
            delOtherCachedViews(view);
            resolve({
                visitedViews: [...visitedViews.value],
                cachedViews: [...cachedViews.value]
            });
        });
    }

    function delLeftViews(view: TagView) {
        return new Promise(resolve => {
            const currIndex = visitedViews.value.findIndex(v => v.path === view.path);
            if (currIndex === -1) {
                return;
            }
            visitedViews.value = visitedViews.value.filter((item, index) => {
                // affix:true 固定tag，例如“首页”
                if (index >= currIndex || (item.meta && item.meta.affix)) {
                    return true;
                }

                const cacheIndex = cachedViews.value.indexOf(item.name as string);
                if (cacheIndex > -1) {
                    cachedViews.value.splice(cacheIndex, 1);
                }
                return false;
            });
            resolve({
                visitedViews: [...visitedViews.value]
            });
        });
    }
    function delRightViews(view: TagView) {
        return new Promise(resolve => {
            const currIndex = visitedViews.value.findIndex(v => v.path === view.path);
            if (currIndex === -1) {
                return;
            }
            visitedViews.value = visitedViews.value.filter((item, index) => {
                // affix:true 固定tag，例如“首页”
                if (index <= currIndex || (item.meta && item.meta.affix)) {
                    return true;
                }

                const cacheIndex = cachedViews.value.indexOf(item.name as string);
                if (cacheIndex > -1) {
                    cachedViews.value.splice(cacheIndex, 1);
                }
                return false;
            });
            resolve({
                visitedViews: [...visitedViews.value]
            });
        });
    }

    function delAllViews() {
        return new Promise(resolve => {
            const affixTags = visitedViews.value.filter(tag => tag.meta?.affix);
            visitedViews.value = affixTags;
            cachedViews.value = [];
            resolve({
                visitedViews: [...visitedViews.value],
                cachedViews: [...cachedViews.value]
            });
        });
    }

    function delAllVisitedViews() {
        return new Promise(resolve => {
            const affixTags = visitedViews.value.filter(tag => tag.meta?.affix);
            visitedViews.value = affixTags;
            resolve([...visitedViews.value]);
        });
    }

    function delAllCachedViews() {
        return new Promise(resolve => {
            cachedViews.value = [];
            resolve([...cachedViews.value]);
        });
    }

    return {
        visitedViews,
        cachedViews,
        addVisitedView,
        addCachedView,
        delVisitedView,
        delCachedView,
        delOtherVisitedViews,
        delOtherCachedViews,
        updateVisitedView,
        addView,
        delView,
        delOtherViews,
        delLeftViews,
        delRightViews,
        delAllViews,
        delAllVisitedViews,
        delAllCachedViews
    };
});
